package com.xiepxcc.annotation.base.ahandle;

import com.xiepxcc.annotation.base.anno.RegisteredAnnotation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Component
public class RegisteredAnnotationHandle implements ApplicationContextAware, InitializingBean {
    private ApplicationContext applicationContext;

    private List<String> allRegistered = new ArrayList<>();

    @Override
    public void afterPropertiesSet() throws Exception {
        scanClass();
        scanMethod();
        scanProp();
        System.out.println(allRegistered);
    }

    /**
     * 查找 用 RegisteredAnnotation 注解的 类
     * @throws Exception
     */
    private void scanClass() throws Exception {
        final Map<String, Object> permissionMap = applicationContext.getBeansWithAnnotation(RegisteredAnnotation.class);
        for (final Object permissionObject : permissionMap.values()) {
            final Class<? extends Object> permissionClass = permissionObject.getClass();
            //此处有坑
//            final RegisteredAnnotation annotation = permissionClass.getAnnotation(RegisteredAnnotation.class);
//            System.out.println(permissionClass.getName());
//            System.out.println(permissionClass.isAnnotationPresent(RegisteredAnnotation.class));
//            System.out.println(permissionClass.getAnnotations());
            final RegisteredAnnotation annotation = AnnotationUtils.findAnnotation(permissionClass,RegisteredAnnotation.class);
            if(annotation != null) {
                allRegistered.addAll(Arrays.asList(annotation.name()));
            }
        }
    }


    /**
     * 查找 用 Component 注解的 类 下面 用 RegisteredAnnotation 注解的方法
     * @throws Exception
     */
    private void scanMethod() throws Exception{
        final Map<String, Object> controllerMap = applicationContext.getBeansWithAnnotation(Component.class);
        for (final Object controllerObject : controllerMap.values()) {
            final Class<? extends Object> controllerClass = controllerObject.getClass();
            for (Method method : controllerClass.getDeclaredMethods()) {
//                RegisteredAnnotation annotation = method.getAnnotation(RegisteredAnnotation.class);
                RegisteredAnnotation annotation = AnnotationUtils.findAnnotation(method,RegisteredAnnotation.class);
                if (annotation != null) {
                    allRegistered.addAll(Arrays.asList(annotation.name()));
                }
            }
        }
    }

    private void scanProp() throws Exception{
        final Map<String, Object> controllerMap = applicationContext.getBeansWithAnnotation(Component.class);
        for (final Object controllerObject : controllerMap.values()) {
            final Class<? extends Object> controllerClass = controllerObject.getClass();
            for (Field field : controllerClass.getFields()) {
                RegisteredAnnotation annotation = AnnotationUtils.findAnnotation(field,RegisteredAnnotation.class);
                if (annotation != null) {
                    allRegistered.addAll(Arrays.asList(annotation.name()));
                }
            }
        }
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }
}